package com.zeei.bfs.controller;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.PageInfo;
import com.zeei.bfs.common.constant.BFSConstant;
import com.zeei.bfs.dao.SysLogDao;
import com.zeei.bfs.service.SessionService;
import com.zeei.bfs.service.UserService;
import com.zeei.bfs.vo.QueryUserParamVO;
import com.zeei.common.algorithm.CryptographyUtil;
import com.zeei.common.annotation.SysLog;
import com.zeei.common.constant.GlobalConstant;
import com.zeei.common.controller.BasicController;
import com.zeei.common.enums.LogType;
import com.zeei.common.utils.SessionInfoUtil;
import com.zeei.common.utils.StringUtil;
import com.zeei.common.utils.UserOperationLog;
import com.zeei.common.vo.ResultBasicVO;
import com.zeei.common.vo.ResultRowsVO;
import com.zeei.common.vo.UserVO;

@Controller
@RequestMapping(value = "/bfs/user")
public class UserController extends BasicController {
	public static final Log LOGGER = LogFactory.getLog(UserController.class);
	// 用户初始化密码
	private static final String INIT_PASSWORD = "207CF410532F92A47DEE245CE9B11FF71F578EBD763EB3BBEA44EBD043D018FB";

	@Resource
	private UserService userService;

	@Resource
	private SessionService sessionService;

	@Resource
	private SysLogDao syslogDao;
	
	@ResponseBody
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@SysLog(text = "系统登录", type = LogType.Login)
	public ResultBasicVO login(String userName, String password) {
		ResultBasicVO resultVO = new ResultBasicVO();
		UsernamePasswordToken token = new UsernamePasswordToken(userName, com.zeei.common.algorithm.CryptographyUtil.EncryptMd5Hash(password));
		Subject currentUser = SecurityUtils.getSubject();

		try {
			currentUser.login(token);
		} catch (UnknownAccountException e) {
			LOGGER.error(e);
			resultVO.setResult(GlobalConstant.FAILED);
			resultVO.setMessage("账号或密码错误!");
			return resultVO;
		} catch (CredentialsException e) {
			LOGGER.error(e);
			resultVO.setResult(GlobalConstant.FAILED);
			resultVO.setMessage("账号或密码错误 !");
			return resultVO;
		} catch (DisabledAccountException e) {
			LOGGER.error(e);
			resultVO.setResult(GlobalConstant.FAILED);
			resultVO.setMessage("账号被禁用了!");
			return resultVO;
		}

		Session session = currentUser.getSession(false);
		UserVO userInfo = userService.getSessionUserInfoVO(userName);
		HashMap<String, Object> hashMap = new HashMap<>();
		// String
		// sessionId=session.getId().toString()+UUID.randomUUID().toString().replaceAll("-",
		// "");
		String sessionId = session.getId().toString();

		hashMap.put("sessionid", sessionId);
		hashMap.put("sessionname", "Session_User");
		hashMap.put("sessioncontent", userInfo.getUserid().toString());
		hashMap.put("userid", userInfo.getUserid().toString());
		sessionService.deleteSessionByUserId(userInfo.getUserid());
		sessionService.saveUserSession(hashMap);
		session.setAttribute(GlobalConstant.SESSION_USER, userInfo);
		session.setAttribute(GlobalConstant.SESSION_ID, sessionId);
		String[] url = StringUtils.split(request.getRequestURL().toString(), '/');
		String bfsUrl = url[0] + "//" + url[1] + "/" + url[2];
		session.setAttribute(GlobalConstant.BFS_URL, bfsUrl);
		session.setAttribute(GlobalConstant.ExpiringDate, "");
		Cookie cookie = new Cookie("sid", sessionId);
		cookie.setMaxAge(3600 * 24);
		cookie.setPath("/");
		response.addCookie(cookie);
		if (StringUtil.isNotEmpty(userInfo.getSkin())) {
			cookie = new Cookie("cookieskin", userInfo.getSkin());
			cookie.setMaxAge(3600 * 24);
			cookie.setPath("/");
			response.addCookie(cookie);
		}
		resultVO.setResult(GlobalConstant.SUCCEED);
		
		syslogDao.insert(UserOperationLog.getSysLogVO(request, "用户, 执行 系统登录 操作.", LogType.Login));
		return resultVO;
	}

	@RequestMapping(value = "/islogin", method = RequestMethod.GET)
	@ResponseBody
	public ResultBasicVO checkUserLogin() {
		HttpSession session = request.getSession(false);
		ResultBasicVO resultVO = new ResultBasicVO();
		if (session == null) {
			resultVO.setResult(GlobalConstant.FAILED);
		}
		
		return resultVO;
	}

	@RequestMapping(value = "/loginout", method = RequestMethod.POST)
	@ResponseBody
	public ResultBasicVO loginOut(String userId) {
		syslogDao.insert(UserOperationLog.getSysLogVO(request, "用户, 执行 系统退出 操作.", LogType.LoginOut));
		ResultBasicVO resultVO = new ResultBasicVO();
		Subject currentUser = SecurityUtils.getSubject();
		sessionService.deleteSessionBySessionId(SessionInfoUtil.getSessionId());

		currentUser.logout();
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (int i = 0; i < cookies.length; i++) {
				if ("sid".equals(cookies[i].getName())) {
					Cookie cookie = new Cookie("sid", "");// 这边得用"",不能用null
					cookie.setPath("/");// 设置成跟写入cookies一样的
					cookie.setMaxAge(0);
					response.addCookie(cookie);
				}
			}
		}
		resultVO.setResult(GlobalConstant.SUCCEED);
		return resultVO;
	}

	@RequestMapping(value = "/init/password", method = RequestMethod.POST)
	@ResponseBody
	@SysLog(text = "初始化密码", type = LogType.Edit)
	public ResultBasicVO initPassword(UserVO userVO) {
		syslogDao.insert(UserOperationLog.getSysLogVO(request, " 执行 初始化加密 操作.", LogType.LoginOut));
		userVO.setLoginpw(CryptographyUtil.EncryptMd5Hash(INIT_PASSWORD));

		userService.updateToDefaultPassword(userVO);
		return this.createResultBasicVO(true, "密码初始化成功, 初始化密码为【123456】!");
	}

	@RequestMapping(value = "/repassword", method = RequestMethod.POST)
	@ResponseBody
	@SysLog(text = "修改密码", type = LogType.Edit)
	public ResultBasicVO rePassword(UserVO userVO) {
		boolean flag = userService.updatePassword(userVO);
		String msg = "修改成功";
		if (!flag) {
			msg = BFSConstant.RET_OLDPSW_FAILED;
		}
		return this.createResultBasicVO(flag, msg);
	}

	@RequestMapping(value = "/getUserInfo", method = RequestMethod.POST)
	@ResponseBody
	public UserVO getLoginUserInfo() {
		return SessionInfoUtil.getSessionUserInfo();
	}

	@RequestMapping(value = "/list", method = RequestMethod.POST)
	@ResponseBody
	public ResultRowsVO<UserVO> queryUser(QueryUserParamVO queryUserParam) {
		UserVO userInfo = SessionInfoUtil.getSessionUserInfo();
		PageInfo<UserVO> userPage = userService.queryUser(queryUserParam, userInfo);
		return this.createResultRowsVO(userPage.getList(), true, null, (int) userPage.getTotal());
	}

	@RequestMapping(value = "/add", method = RequestMethod.POST)
	@ResponseBody
	@SysLog(text = "新增用户")
	public ResultBasicVO addUser(UserVO user) {
		Integer userId = SessionInfoUtil.getSessionUserId();
		user.setCreateid(userId);
		if (user.getInvalidtime().equals("1900-01-01") || user.getInvalidtime() == "") {
			user.setInvalidtime(null);
		}
		Integer addUserId = userService.addUser(user);
		syslogDao.insert(UserOperationLog.getSysLogVO(request, " 执行 新增"+user.getUsername()+"的用户信息 操作.", LogType.Add));
		return this.createResultDataVO(addUserId, true, null);
	}

	@RequestMapping(value = "/valid", method = RequestMethod.POST)
	@ResponseBody
	public ResultBasicVO validUserLoginName(UserVO user) {
		return this.createResultBasicVO(userService.validUserLoginName(user), null);
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	@ResponseBody
	@SysLog(text = "编辑用户", type = LogType.Edit)
	public ResultBasicVO editUser(UserVO user) {
		syslogDao.insert(UserOperationLog.getSysLogVO(request, " 执行 编辑"+user.getUsername()+"的用户信息 操作.", LogType.Edit));
		if (user.getInvalidtime().equals("1900-01-01") || user.getInvalidtime() == "") {
			user.setInvalidtime(null);
		}
		return this.createResultBasicVO(userService.editUser(user), null);
	}

	@RequestMapping(value = "/drop", method = RequestMethod.POST)
	@ResponseBody
	@SysLog(text = "删除用户", type = LogType.Edit)
	public ResultBasicVO dropUser(String userIds) {
		List<String> list = StringUtil.splitToList(userIds);
		String selfUserId = SessionInfoUtil.getCurrentStringUserId();
		if (existSelfUser(list, selfUserId)) {
			// deleteSelfUser(list,selfUserId);
			return this.createResultBasicVO(false, "不可以删除自己!");
		}
		syslogDao.insert(UserOperationLog.getSysLogVO(request, " 执行 删除ID为"+userIds+"的用户信息 操作.", LogType.Delete));

		return this.createResultBasicVO(userService.dropUser(list), null);
	}

	private boolean existSelfUser(List<String> userIdList, String selfUserId) {
		boolean existSelfUser = false;
		for (String userId : userIdList) {
			if (selfUserId.equals(userId)) {
				existSelfUser = true;
				break;
			}
		}
		return existSelfUser;
	}

	/**
	 * 方法描述:删除掉登录用户自身的ID
	 *
	 * @param userIdList
	 * @param selfUserId
	 */
	private void deleteSelfUser(List<String> userIdList, String selfUserId) {
		if (selfUserId != null && CollectionUtils.isNotEmpty(userIdList)) {
			Iterator<String> it = userIdList.iterator();
			while (it.hasNext()) {
				String userId = it.next();
				if (selfUserId.equals(userId)) {
					it.remove();
				}
			}
		}
	}

	@RequestMapping(value = "/queryUserByLoginName", method = RequestMethod.POST)
	@ResponseBody
	public UserVO queryUserByLoginName(String username) {
		UserVO queryVO = new UserVO();
		queryVO.setLoginname(username);
		return userService.queryUserByLoginName(queryVO);
	}

	@RequestMapping(value = "/querySessionUserInfo", method = RequestMethod.POST)
	@ResponseBody
	public UserVO querySessionUserInfo(String sessionId) {
		UserVO userInfo = sessionService.querySessionById(sessionId);
		userInfo.setSessionId(sessionId);
		return userInfo;
	}

	@RequestMapping(value = "/combobox", method = RequestMethod.POST)
	@ResponseBody
	public List<UserVO> queryComboboxUser(String searchUserName) {
		UserVO userVO = SessionInfoUtil.getSessionUserInfo();
		return userService.queryAllUser(searchUserName, userVO);
	}

	@RequestMapping(value = "/updateSkin", method = RequestMethod.POST)
	@ResponseBody
	@SysLog(text = "修改皮肤", type = LogType.Edit)
	public ResultBasicVO updateSkin(String skin) {
		UserVO userVO = new UserVO();
		userVO.setSkin(skin);
		boolean flag = userService.updateSkin(userVO);
		String msg = "修改成功";
		if (!flag) {
			msg = BFSConstant.RET_OLDPSW_FAILED;
		}
		syslogDao.insert(UserOperationLog.getSysLogVO(request, " 执行 修改皮肤 操作.", LogType.Edit));
		
		return this.createResultBasicVO(flag, msg);
	}
}
